﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework;

namespace Brain.Rendering
{
    public class ShapeDrawer
    {
        public Dictionary<Type, Shape> Shapes { get; protected set; }

        public BasicEffect BasicEffect { get; protected set; }

        public VertexPositionColor[] LightVertices { get; protected set; }

        public List<object> ToDraw;

        public ShapeDrawer()
        {
            Shapes = new Dictionary<Type, Shape>();
            Shapes.Add(typeof(BoundingBox), new Shape_BoundingBox());
            Shapes.Add(typeof(BoundingSphere), new Shape_BoundingSphere());
            Shapes.Add(typeof(BoundingFrustum), new Shape_BoundingFrustum());
            Shapes.Add(typeof(Line3D), new Shape_Line3D());

            ToDraw = new List<object>();

            this.BasicEffect = new BasicEffect(Engine.Instance.GraphicsDevice);

            LightVertices = new VertexPositionColor[]
            {
                new VertexPositionColor(new Vector3(0, 1, 0), Color.Red),
                new VertexPositionColor(new Vector3(1, 0, 0), Color.Red),
                new VertexPositionColor(new Vector3(0, 1, 0), Color.Red),
                new VertexPositionColor(new Vector3(1, 0, 0), Color.Red)
            };
        }

        public void Submit(object obj)
        {
            ToDraw.Add(obj);
        }
        public void Submit(object obj, Color color)
        {
            ToDraw.Add(new ShapeColor() { Object = obj, Color = color });
        }



        public void DrawEverything(ICamera3D Camera)
        {
            GraphicsDevice device = Engine.Instance.GraphicsDevice;

            BasicEffect.View = Camera.View;
            BasicEffect.Projection = Camera.Projection;
            BasicEffect.World = Matrix.Identity;

            for (int i = 0; i < ToDraw.Count; i++)
            {
                object obj = ToDraw[i];

                Color color = Color.Red;

                if (obj is ShapeColor)
                {
                    ShapeColor s = (ShapeColor)obj;
                    obj = s.Object;
                    color = s.Color;
                }

                Type t = obj.GetType();
                if (this.Shapes.ContainsKey(t))
                {
                    Shape shape = this.Shapes[t];

                    BasicEffect.VertexColorEnabled = shape.UseVertexColor;

                    shape.Draw(obj, color, Camera, this, BasicEffect);
                }
            }

            ToDraw.Clear();
        }

        public void Draw(object obj, Color color, ICamera3D Camera)
        {
            object ob = obj;

            Type t = obj.GetType();
            if (this.Shapes.ContainsKey(t))
            {
                Shape shape = this.Shapes[t] as Shape;

                BasicEffect.View = Camera.View;
                BasicEffect.Projection = Camera.Projection;
                BasicEffect.World = Matrix.Identity;

                shape.Draw(obj, color, Camera, this, BasicEffect);
            }
        }

        public void Reset()
        {
            if (!this.BasicEffect.IsDisposed)
            {
                this.BasicEffect.Dispose();
            }

            ToDraw.Clear();
            ToDraw.Capacity = 0;

            this.BasicEffect = new BasicEffect(Engine.Instance.GraphicsDevice);
        }
    }
}
